<?php

declare(strict_types=1);

namespace app\sys\controller;

use app\sys\service\SystemMenuService;
use think\admin\Controller;
use think\admin\model\SysRelation;
use think\admin\model\SysRole;
use think\admin\model\SysUser;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 角色接口
 * Class Role
 * @package app\sys\controller
 */
class Role extends Controller
{
    /**
     * 角色分页列表
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function page()
    {
        $query = SysRole::mQuery();
        $query->where(['is_deleted' => 0]);

        // 数据列表搜索过滤
        $query->equal('status')->dateBetween('create_time');
        $query->like('name,category');
        $query->dataScope('created_by');
        $lists = $query->order('sort ASC,id ASC')->page();
    }

    /**
     * 获取一条角色详情
     * @auth true
     * @return void
     */
    public function detail()
    {
        sysoplog('角色管理', '角色详情获取成功');
        $this->success('操作成功', SysRole::detail((int)$this->request->param('id')));
    }

    /**
     * 添加角色
     * @auth true
     * @return void
     */
    public function add()
    {
        sysoplog('角色管理', '角色添加成功');
        SysRole::mForm('form');
    }

    /**
     * 更新角色
     * @auth true
     * @return void
     */
    public function edit()
    {
        sysoplog('角色管理', '角色更新成功');
        SysRole::mForm('form');
    }

    /**
     * 修改角色状态
     * @auth true
     * @return void
     */
    public function state()
    {
        sysoplog('角色管理', '角色修改成功');
        SysRole::mSave($this->_vali([
            'status.in:0,1' => '状态值范围异常！',
            'status.require' => '状态值不能为空！',
        ]));
    }

    /**
     * 查询角色已授权用户
     * @auth true
     * @return void
     */
    public function ownUser()
    {
        $users = SysRelation::getTargetIds('SYS_ROLE_HAS_USER', $this->request->param('id'));
        sysoplog('角色管理', '角色授权用户成功');
        $this->success('获取成功！', $users);
    }

    /**
     * 资源选择器
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function resourceTreeSelector()
    {
        $menus = SystemMenuService::instance()->getResourceTree();
        $this->success('获取成功！', $menus);
    }

    /**
     * 权限选择器
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function permissionTreeSelector()
    {
        $permissions = SystemMenuService::instance()->getPermissions($this->request->param('category', 'biz'));
        $this->success('获取成功！', $permissions);
    }

    /**
     * 移动端资源选择器
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function mobileMenuTreeSelector()
    {
        $menus = SystemMenuService::instance()->getResourceTree();
        $this->success('获取成功！',$menus);
    }

    /**
     * 查询角色已授权的资源
     * @auth true
     * @return void
     */
    public function ownResource()
    {
        $roleId = $this->request->param('id');

        if (!$roleId) {
            $this->error('角色ID未提供。');
            return;
        }

        $extJsonList = SysRelation::mk()
            ->whereIn('object_id', $roleId)
            ->where(['category' => 'SYS_ROLE_HAS_RESOURCE'])
            ->column('ext_json');

        $grantInfoList = array_map(function($extJson) {
            $data = json_decode($extJson, true);
            if (!isset($data['buttonInfo'])) {
                $data['buttonInfo'] = [];
            }
            return $data;
        }, $extJsonList);

        $data = [
            'id' => $roleId,
            'grantInfoList' => $grantInfoList
        ];

        $this->success('获取成功！', $data);
    }


    /**
     * 查询角色已授权的权限
     * @auth true
     * @return void
     */
    public function ownPermission()
    {
        $roleId = $this->request->param('id');

        if (!$roleId) {
            $this->error('角色ID未提供。');
            return;
        }

        $extJsonList = SysRelation::mk()
            ->whereIn('object_id', $roleId)
            ->where(['category' => 'SYS_ROLE_HAS_PERMISSION'])
            ->column('ext_json');

        $grantInfoList = array_map(function($extJson) {
            return json_decode($extJson, true);
        }, $extJsonList);

        $data = [
            'id' => $roleId,
            'grantInfoList' => $grantInfoList
        ];

        $this->success('获取成功！', $data);
    }


    /**
     * 移动端角色已授权资源
     * @auth true
     * @return void
     */
    public function ownMobileMenu()
    {
        $roleId = $this->request->param('id');

        if (!$roleId) {
            $this->error('角色ID未提供。');
            return;
        }

        $extJsonList = SysRelation::mk()
            ->whereIn('object_id', $roleId)
            ->where(['category' => 'SYS_ROLE_HAS_MOBILE_RESOURCE'])
            ->column('ext_json');

        $grantInfoList = array_map(function($extJson) {
            $data = json_decode($extJson, true);
            if (!isset($data['buttonInfo'])) {
                $data['buttonInfo'] = [];
            }
            return $data;
        }, $extJsonList);

        $data = [
            'id' => $roleId,
            'grantInfoList' => $grantInfoList
        ];

        $this->success('获取成功！', $data);

    }


    /**
     * 主管选择器
     * @auth true
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function userSelector()
    {
        $query = SysUser::mQuery();
        $query->where(['is_deleted' => 0, 'status' => 0]);

        // 数据列表搜索过滤
        $query->like('category');
        $query->field('id,name,account');
        $users = $query->order('id ASC')->page(false,false,false);
        sysoplog('账号管理', '主管选择器获取成功');
        $this->success('数据获取成功', $users['list']);
    }

    /**
     * 角色资源授权
     * @auth true
     * @return void
     * @throws DbException
     */
    public function grantResource()
    {
        $id = $this->request->post('id');
        $grantInfoList = $this->request->post('grantInfoList');

        if (!$id) {
            $this->error('角色ID不存在，资源授权失败。');
            return;
        }

        $this->app->db->transaction(function () use ($id, $grantInfoList) {
            SysRelation::mk()->where(['object_id' => $id, 'category' => 'SYS_ROLE_HAS_RESOURCE'])->delete();
            if (!empty($grantInfoList)) {
                $data = [];
                foreach ($grantInfoList as $v) {
                    $data[] = [
                        'object_id' => $id,
                        'target_id' => $v['menuId'],
                        'category' => 'SYS_ROLE_HAS_RESOURCE',
                        'ext_json' => json_encode($v)
                    ];
                }
                if (!SysRelation::mk()->insertAll($data)) {
                    // 如果插入失败，抛出异常会导致事务自动回滚
                    throw new \Exception('资源授权失败');
                }
            }
        });

        $this->success(!empty($grantInfoList) ? '资源授权成功' : '资源授权已删除');
    }


    /**
     * 移到回收站
     * @auth true
     * @return void
     */
    public function delete()
    {
        sysoplog('角色管理', '角色删除成功');
        SysRole::mSave(['is_deleted' => 1]);
    }

    /**
     * 角色授权用户
     * @auth true
     * @return void
     * @throws DbException
     */
    public function grantUser()
    {
        $id = $this->request->post('id');
        $grantInfoList = $this->request->post('grantInfoList');

        if (!$id) {
            $this->error('角色ID不存在，用户授权失败。');
            return;
        }

        $this->app->db->transaction(function () use ($id, $grantInfoList) {
            SysRelation::mk()->where(['object_id' => $id, 'category' => 'SYS_ROLE_HAS_USER'])->delete();
            if (!empty($grantInfoList)) {
                $data = array_map(function ($userId) use ($id) {
                    return [
                        'object_id' => $id,
                        'target_id' => $userId,
                        'category' => 'SYS_ROLE_HAS_USER'
                    ];
                }, $grantInfoList);

                if (!SysRelation::mk()->insertAll($data)) {
                    // 如果插入失败，抛出异常会导致事务自动回滚
                    throw new \Exception('用户授权失败');
                }
            }
        });

        $this->success(!empty($grantInfoList) ? '用户授权成功' : '用户授权已删除');
    }


    /**
     * 角色授权权限
     * @auth true
     * @return void
     * @throws DbException
     */
    public function grantPermission()
    {
        $id = $this->request->post('id');
        $grantInfoList = $this->request->post('grantInfoList');

        if (!$id) {
            $this->error('角色ID不存在，权限授权失败。');
            return;
        }

        $this->app->db->transaction(function () use ($id, $grantInfoList) {
            SysRelation::mk()->where(['object_id' => $id, 'category' => 'SYS_ROLE_HAS_PERMISSION'])->delete();
            if (!empty($grantInfoList)) {
                $data = [];
                foreach ($grantInfoList as $v) {
                    // 确保每个权限对象都有 scopeDefineOrgIdList 属性
                    if (!isset($v['scopeDefineOrgIdList'])) {
                        $v['scopeDefineOrgIdList'] = [];
                    }
                    $data[] = [
                        'object_id' => $id,
                        'target_id' => $v['apiUrl'],
                        'category' => 'SYS_ROLE_HAS_PERMISSION',
                        'ext_json' => json_encode($v)
                    ];
                }
                if (!SysRelation::mk()->insertAll($data)) {
                    // 如果插入失败，抛出异常会导致事务自动回滚
                    throw new \Exception('权限授权失败');
                }
            }
        });

        $this->success(!empty($grantInfoList) ? '权限授权成功' : '权限授权已删除');
    }

}